package com.yupi.dada.scroring;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yupi.dada.model.dto.question.QuestionContentDTO;
import com.yupi.dada.model.entity.App;
import com.yupi.dada.model.entity.Question;
import com.yupi.dada.model.entity.ScoringResult;
import com.yupi.dada.model.entity.UserAnswer;
import com.yupi.dada.model.vo.QuestionVO;
import com.yupi.dada.service.QuestionService;
import com.yupi.dada.service.ScoringResultService;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 自定义测评类应用评分策略
 */
@ScoringStrategyConfig(appType = 1, scoringStrategy = 0)
public class CustomTestScroingStrategy implements ScroingStrategy {

    @Resource
    private QuestionService questionService;

    @Resource
    private ScoringResultService scoringResultService;

    @Override
    public UserAnswer doScore(List<String> choices, App app) throws Exception {
        Long appId = app.getId();
        // 1. 根据id查询到题目和题目的结果信息
        Question question = questionService.getOne(
                Wrappers.lambdaQuery(Question.class).eq(Question::getAppId, appId)
        );
        List<ScoringResult> scoringResultList = scoringResultService.list(
                Wrappers.lambdaQuery(ScoringResult.class).eq(ScoringResult::getAppId, appId)
        );

        // 2. 统计用户每个选择对应的属性个数,如 I = 10 个, E = 5 个
        //初始化一个Map,用来存储每个选项对应的属性个数
        Map<String, Integer> optionCount = new HashMap<>();

        // 将Question对象转换为QuestionVO对象
        QuestionVO questionVO = QuestionVO.objToVo(question);
        // 获取题目的内容列表
        List<QuestionContentDTO> questionContent = questionVO.getQuestionContent();

        // 遍历题目列表
        for (QuestionContentDTO questionContentDTO : questionContent) {
            // 遍历用户的选择
            for (String answer : choices) {
                // 遍历题目选项
                for (QuestionContentDTO.Option option : questionContentDTO.getOptions()) {
                    // 如果选项的键与用户的选择匹配
                    if (option.getKey().equals(answer)) {
                        // 获取该选项对应的属性结果
                        String result = option.getResult();
                        // 如果Map中不包含该属性结果,则初始化为0
                        if (!optionCount.containsKey(result)) {
                            optionCount.put(result, 0);
                        }
                        // 将该属性结果的计数加1
                        optionCount.put(result, optionCount.get(result) + 1);
                    }
                }
            }
        }

        // 3. 遍历每种评分结果,计算哪个结果的得分更高
        int maxScore = 0; // 初始化最高分数为0
        ScoringResult maxScoringResult = scoringResultList.get(0); // 初始化最高分数对应的评分结果为列表中的第一个

        //遍历评分结果列表
        for (ScoringResult scoringResult : scoringResultList) {
            // 将评分结果中的属性结果字符串转换为List
            List<String> resultProp = JSONUtil.toList(scoringResult.getResultProp(), String.class);
            // 计算当前评分结果的分数, [I,E] => [10,5] => 15
            int score = resultProp.stream().mapToInt(prop -> optionCount.getOrDefault(prop, 0)).sum();

            //如果分数高于当前最高分数,更新最高分数和最高分数对应的评分结果
            if (score > maxScore) {
                maxScore = score; // 更新最高分数
                maxScoringResult = scoringResult; // 更新最高分数对应的评分结果
            }
        }

        // 4. 构造返回值,填充答案对应的属性
        UserAnswer userAnswer = new UserAnswer();
        userAnswer.setAppId(appId);
        userAnswer.setAppType(app.getAppType());
        userAnswer.setScoringStrategy(app.getScoringStrategy());
        userAnswer.setChoices(JSONUtil.toJsonStr(choices));
        userAnswer.setResultId(maxScoringResult.getId());
        userAnswer.setResultName(maxScoringResult.getResultName());
        userAnswer.setResultDesc(maxScoringResult.getResultDesc());
        userAnswer.setResultPicture(maxScoringResult.getResultPicture());

        return userAnswer;
    }
}